package com.ifp.opengate.boot.utils;

import static com.ifp.opengate.boot.constants.Constants.FRAGMENT_KEY;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import com.ifp.adapter.common.AdapterCanstants;
import com.ifp.adapter.message.field.MessageField;
import com.ifp.adapter.message.head.DefaultHead;
import com.ifp.core.base.Constants;
import com.ifp.core.context.ClogicContext;
import com.ifp.core.util.DateUtil;
import com.ifp.core.util.SpringContextsUtil;
import com.ifp.opengate.boot.emum.ErrorEnum;

/**
 * @author zhai
 * @package com.ifp.springcloud.gateway.util
 * @description 响应报文工具类
 * @date 2020/7/28 20:48
 */
@Component("responseUtil")
public class ResponseUtil {

    @Autowired
    private UniErrCodeUtils uniErrCodeUtils;
    // 响应报文头模板定义beanId
    private final static String RESPONSE_DEADER = "httpResponseHead";

    /**
     * 创建标准响应报文头
     * 
     * @param headerMap
     * @return
     */
    public static Map<String, Object> createStandardResponseHeader(Map<String, Object> headerMap) {
        DefaultHead httpResponseHead = (DefaultHead)SpringContextsUtil.getBean(RESPONSE_DEADER);
        List<MessageField> fieldList = httpResponseHead.getFieldOrder();
        Map<String, Object> statdardHeaderMap = new HashMap<String, Object>();
        for (int i = 0; i < fieldList.size(); i++) {
            MessageField messageField = fieldList.get(i);
            String temp_name = messageField.getName();
            statdardHeaderMap.put(temp_name, (null == headerMap.get(temp_name) || "".equals(headerMap.get(temp_name)))
                ? "" : headerMap.get(temp_name));
        }
        // 设置非必须返回的字段置为 "",及默认数据
        statdardHeaderMap.put("charset", "UTF-8");
        // 异常处理
        if (statdardHeaderMap != null && !ErrorEnum.success.code().equals(statdardHeaderMap.get(Constants.ERRORCODE))) {
            statdardHeaderMap.put(FRAGMENT_KEY, "");
            statdardHeaderMap.put("signData", "");
        }
        headerMap.clear();
        headerMap.putAll(statdardHeaderMap);
        return statdardHeaderMap;
    }

    public static String createResponseId(String appId, int len) {
        String ranDom = "";
        if (len > 0) {
            ranDom = getRandom(len);
        }
        return new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + appId + ranDom;
    }

    public static String getRandom(int len) {
        int rs = (int)((Math.random() * 9 + 1) * Math.pow(10, len - 1));
        return String.valueOf(rs);
    }

    /**
     * 将报文header的错误信息装载到报文body
     * 
     * @param header
     * @param bodyMap
     */
    public static Map<String, Object> headerErrorInfoToBody(Map<String, Object> header, Map<String, Object> bodyMap) {
        if (null == bodyMap) {
            bodyMap = new HashMap<String, Object>();
        } else {
            bodyMap.clear();
        }
        bodyMap.put(com.ifp.opengate.boot.constants.Constants.JH_BUSINESS_RESPONSE_CODE,
            header.get(Constants.ERRORCODE));
        bodyMap.put(com.ifp.opengate.boot.constants.Constants.JH_BUSINESS_RESPONSE_MSG, header.get(Constants.ERRORMSG));
        return bodyMap;
    }

    /**
     * 异常情况下 创建标准响应报文头
     * 
     * @param serverWebExchange
     * @return
     */
    public Map<String, Object> createExceptionStandardResponseHeader(ServerWebExchange serverWebExchange) {
        Map<String, Object> headerExchangeMap =
            (Map<String, Object>)serverWebExchange.getAttribute("cachedRequestBodyObject");
        Map<String, String> headerMap = (Map<String, String>)headerExchangeMap.get(AdapterCanstants.HEADER);
        String appId = headerMap.get(com.ifp.opengate.boot.constants.Constants.APPID);
        DefaultHead httpResponseHead = (DefaultHead)SpringContextsUtil.getBean(RESPONSE_DEADER);
        List<MessageField> fieldList = httpResponseHead.getFieldOrder();

        Map<String, Object> statdardHeaderMap = new HashMap<String, Object>();
        for (int i = 0; i < fieldList.size(); i++) {
            MessageField messageField = fieldList.get(i);
            String temp_name = messageField.getName();
            statdardHeaderMap.put(temp_name, (null == headerMap.get(temp_name) || "".equals(headerMap.get(temp_name)))
                ? "" : headerMap.get(temp_name));
        }
        // 设置非必须返回的字段置为 "",及默认数据
        statdardHeaderMap.put(com.ifp.opengate.boot.constants.Constants.RESPONSE_ID,
            ResponseUtil.createResponseId(appId, 3));
        String responseTime = DateUtil.getUserDate("yyyyMMddHHmmss");
        statdardHeaderMap.put(com.ifp.opengate.boot.constants.Constants.RESPONSE_TIME, responseTime);
        statdardHeaderMap.put(com.ifp.opengate.boot.constants.Constants.CHARSET, "UTF-8");
        statdardHeaderMap.put(com.ifp.opengate.boot.constants.Constants.SIGN_DATA, "");
        statdardHeaderMap.put(FRAGMENT_KEY, "");
        statdardHeaderMap.put(Constants.ERRORCODE, ErrorEnum.notFound.code());
        statdardHeaderMap.put(Constants.ERRORMSG, ErrorEnum.notFound.msg());
        errorCodeMappingHandler(
            (ClogicContext)serverWebExchange.getAttributes().get(com.ifp.opengate.boot.constants.Constants.CL_CONTEXT),
            statdardHeaderMap);
        return statdardHeaderMap;
    }

    /**
     *
     * @param clogicContext
     * @param headerMap
     */
    public void errorCodeMappingHandler(ClogicContext clogicContext, Map<String, Object> headerMap) {
        String apiCodeVer = null;
        String apiCode = null;
        String errorCode = (String)headerMap.get(com.ifp.opengate.boot.constants.Constants.ERROR_CODE);
        String errorMsg = (String)headerMap.get(com.ifp.opengate.boot.constants.Constants.ERROR_MSG);
        String apiVersion = (String)headerMap.get(com.ifp.opengate.boot.constants.Constants.VERSION);
        String sysCode = (String)headerMap.get(com.ifp.opengate.boot.constants.Constants.SUBCRIBE_SYSTEM_ID);
        String channel = (String)headerMap.get(com.ifp.opengate.boot.constants.Constants.APP_ID);
        Map codeInfo = uniErrCodeUtils.getUniErrCodeInfo(errorCode, errorMsg, apiCodeVer, sysCode, channel);
        if (codeInfo != null && codeInfo.size() > 0) {
            headerMap.put(com.ifp.opengate.boot.constants.Constants.ERROR_CODE,
                codeInfo.get(com.ifp.opengate.boot.constants.Constants.ERROR_CODE));
            headerMap.put(com.ifp.opengate.boot.constants.Constants.ERROR_MSG,
                codeInfo.get(com.ifp.opengate.boot.constants.Constants.ERROR_MSG));
        }
    }
}
